
// pages/guihua/guihua.js
import utils from '../../utils/util.js';
const tool = require("./tool/Request.js")
Page({

  /**
   * 页面的初始数据
   */
  data: {
    //地图的相关初始数据
    position:'relative',
    width:'100%',
    // height:'55vh',
    height:'79vh',
    longitude:'',//地图初始的经纬度
    latitude:'',
    centerLongitude:'',//地图中心的经纬度，在地图拖动地图的时候可以获取到，一般是在获取到附近的店铺的时候可以使用
    centerLatitude:'',

    markers:[],//地图上的标记点，显示用的
    start_point_marker:[],//起点的Marker
    end_point_marker:[],//终点的Marker

    geton_getoff:[],//公交，部分polyline显示的时候，绘制上站和下站的位置

    //==================polyline=============, 依旧是使用覆盖的方式进行数据处理 TAG DATA POLYLINE
    polyline:[],//地图上的曲线
    polyline_route:[],//三条总路线的polyline，
    polyline_part:[],//部分路线的polyline，用来显示每一段的polyline。

    //公交线路的polyline，因为公交线路的数据非常零碎，单靠几个数组进行划分，恐怕是不够的，所以这里直接集合成一个数组了,
    polyline_BUS_collection:[],//这个数据是不能直接使用的，需要处理后才能显示在地图上；
    polyline_BUS_collection_change:[],//这个数据是上面的一个数据的复制，这个数据主要是用来修改的，上面的数据放着备份
    color_polyline:{
      "subway_deep":"#c92a2a",
      "subway_light":"#ff8787",
      "rail_deep":"#364fc7",
      "rail_light":"#748ffc",
      "bus_deep":"#862e9c",
      "bus_light":"#da77f2"
    },//线路颜色，因为公交线路的种类非常多，所以要配置多种颜色进行区分
    currentPolyline_STEP_1:[],//一级步骤的polyline，专门为公交准备

    //====================输入框的相关初始数据==================================
    //起点输入框
    className:'confirm_btn',//确认按钮的类名，动画播放完毕之后自动切换
    cover_start:false,//控制起点输入框下方的蒙皮的出现和消失。输入框进入输入状态的时候出现，默认状态的时候，消失。
    //起点输入框下方的地点数据列表
    locationList:[],
    list_height:'0rpx',//地点数据列表的高度控制，为了效果，做一个无聊的动画
    item_height:'120rpx',//地点推荐列表，单个项目的高度
    list_expand_height:'25vh',//列表展开高度
    list_during: 300,//列表动画播放速度，即展开和收起的速度，播放速度最好快一点，不然容易出现BUG

    clear:false,//清除按钮的显示与否
    searchData:'',//输入框的值
    keyword:'',//用来搜索的关键词，因为输入框的值searchData在点击列表项目之后，会变成item.title，所以需要一个变量来存储之前输入的值

    currentBtn:-1,//负责控制选中项的样式变化
    isLoading_START:false,//用来表示是否正在请求关键词推荐服务

   
    //腾讯位置服务，关键词提示服务的相关数据
     //start_input的
    count:-1,//请求到的提示词条数量，最多100条建议
    page_index:1,//默认page_index
    page_size:10,//默认page大小
    //end_input的
    count_END:-1,
    page_index_END:1,
    page_size_END:10,


    //起点和终点的相关信息
    start_point:{},
    end_point:{},

    //========终点输入框的相关控制变量======================,数据基本与起点输入框一致，但是为了相互独立，还是再写一份数据
    searchData_END:'',//终点输入框内容
    keyword_END:'',//终点的搜索关键词
    className_END:'confirm_btn',//终点输入框确认按钮的类控制
    clear_END:false,//终点输入框的清空按钮控制
    cover_end:false,//终点的遮罩层
    
    //终点输入框
    locationList_END:[],//终点输入框的地点推荐数据
    list_height_END:'0rpx',//动态控制列表的高度
    item_height_END:'120rpx',//单项的高度，默认120rpx
    list_expand_height_END:'25vh',//列表展开高度
    
    currentBtn_END:-1,//控制列表项的选中样式
    isLoading_END:false,//控制列表是否正在加载中


    //==========================地图控制栏======================================
    mapbar:-1,//-1表示默认状态，即收缩状态。1表示展开状态
    map_className: 'Map_origin',//地图的样式控制
    mapBar_className: 'map_bar_img',//控制地图控制栏上面的箭头图标的样式

    //===========================方案选择=======================================
    selectList:["驾车","步行","公交"],//列表项
    currentBtn_SELECT:0,//样式控制，默认第一项激活
    transX:0,//样式控制
    item_width:0,//样式控制,

    //==============================路线规划信息==========================================
    routes:[],//路线方案，一般有3个路线方案，距离过短时，有时候会只有1个路线方案，所以界面设计要慎重
    currentBtn_PLAN:0,//样式控制，默认选中第一个方案

    //右边的详细方案
    currentBtn_STEP:-1,//默认不选中任何步骤
    currentBtn_STEP_2: -2, // 公交的步骤的步骤，因为公交车有二级步骤，所以要特别设置一个

    //=============================其他数据================================================
    what_is_focused:-1,//用来表示哪个属于框处于聚焦状态，-1表示什么都没有聚焦，1表示起始输入框，2表示终点输入框
    search_box:'search-box',//用来控制输入输出框的动画，向上移动或者向下移动。
    route_detail:'route_detail',//用来控制路线方案的动画的（原本可以不使用动画的，但是层级又容易出现问题
    scroll_top_STEP:0,//控制方案详情列表的滚动
    isShowPositioning: false, //控制地图右下角的定位图标
    end_class: 'end',
    start_clas: 'start',
    rocker_class: 'rocker',
    center_longitude:-1,//配合地图右下角定位的
    center_latitude:-1,
    center_location:'',//通过中心标点获取到的地址信息, 用来在界面上显示
    center_point:{},//通过中心点坐标逆地址解析获取到的信息，构建出来的一个点，提供给路径规划使用
  },//TAG DATA

/*******************************************************************************************************************************
 *标签 监听函数 ********************************************************************************************************************
 * *****************************************************************************************************************************
 */

 //TAG LISTEN START
  /************************
   * 起点输入框的几个监听方法
   * **********************
   */
//点击开始输入框
tapStartInputBar(e){
  this.StartGetFocus();
},
//起点输入框得到聚焦时，调用这个方法
StartGetFocus(){
  this.ConfirmDisplay();//确认按钮显示动画
  this.LocationListDisplay();//地点列表显示动画

  //设置目前的输入框聚焦的是起点输入框
  this.setData({
    what_is_focused: 1
  });
},
//起点输入框要失去焦点时，调用这个方法
StartLoseFocus(){
  this.ConfirmDissappear();
  this.LocationListDissappear();
  this.setData({
    what_is_focused: -1
  })
},

  //聚焦，监听函数
  startFocus(e){
    this.StartGetFocus();
  },
  //失去焦点，监听函数
  startBlur(e){
  },

  //确认按钮的监听函数
  confirm_start(e){
    //播放动画，确认按钮在点击之后消失
    console.log("[LISTEN] -- 起点确认");
    this.StartLoseFocus();
  },

  //input框中的值有变动的时候触发的方法
  startSearchInput(e){
    let val = e.detail.value;
    console.log("输入框：",val);

      if(e.detail.value == ''){
        //当输入框的值为空的时候，这里应该做的是，清空输入框，然后播放清除
        this.clearInput();
      }else{
        //设置输入框的内容到全局
        this.setData({
          searchData:e.detail.value,
          keyword:e.detail.value,//关键词同理，只有在输入框的值是用户手动输入的时候，才会改变，点击列表项是不会改变
          clear:true,
          currentBtn:-1,//这个先看看，输入框的值变动的时候，直接将选中列表的样式清除掉
        });

         // 先清空一下locationList，然后再请求地点建议
        this.setData({locationList:[]});
        this.Suggestion_Debounce(this);
        
        console.log("[INFO][LISTEN][START] -- 地点建议：",this.data.locationList);

      }

      //设置动画播放
      this.LocationListDisplay();
  },

  //清除按钮的相关函数(这个只管清空start的，end需要重新写过)
  clearInput(){
    this.setData({
      searchData:'',//输入框内容清空，
      keyword:'',
      clear:false,//清空按钮消失
      currentBtn:-1,//样式控制恢复原样

      locationList:[],
      page_index:1,//请求页面复原

      start_point_marker:[],//相关Marker也清空掉
      start_point:{},

      polyline_route:[],//清空地图的总polyline
      polyline_part:[],//清空地图的part_polyline

      routes:[],//清空掉路线信息
      currentBtn_PLAN:0, // 左边的方案恢复默认
      currentBtn_STEP:-1, //步骤选择，恢复样式
      currentBtn_STEP_2:-1, //二级步骤恢复
      geton_getoff:[],//部分路线上站和下站点也要清空
    });
    //输入框清空之后，相关刷新地方
    this.refreshMarker();
    this.refreshPolyline();
  },

  //起点输入框下方的蒙版，即起点输入框失去焦点
  OntapStartcover(e){
    this.StartLoseFocus();
  },

  /*************************
   *标签 start下面地址推荐列表的相关监听器 TAG LISTEN START LIST
   * ***********************
   */

  //地址列表滚动到底的监听函数, 只是用来延长
  scroll_to_bottom:function(e){
    //如果输入框中没有值，并且locationList已经被清空了，就不要再请求了。
    //这是防止一个BUG，在清空了之后，这个滚动到底的函数居然还会触发。。。。
    if(this.data.locationList.length == 0){
      console.log("locationlist中没有数据，不需要请求下一页")
      return ;
    }
    console.log("滚动到底部了，请求下一页的数据，当前关键词:",this.data.keyword);
    let count = this.data.count;
    let page_size = this.data.page_size;
    let pageNum = count%page_size == 0? (count/page_size) : (count/page_size + 1);

    if(this.data.page_index < pageNum){//如果不是最底部的一页，那就发送请求，请求数据
      this.setData({
        page_index:this.data.page_index + 1,
      });
      this.Suggestion_Debounce(this)
    }
  },

  //点击列表项的监听方法
  tapListItem(e){
    this.selectStyleControll(e);
    console.log("[LISTEN][LIST][START] -- 选择地点：",e.currentTarget.dataset.item);
    let data = e.currentTarget.dataset.item;
    this.setData({//保存将其保存为起点数据
      start_point:data,
      searchData:data.title,//看看将标题设置到输入框中会不会导致刷新
    });

    //移动地图中心并且绘制起点Marker
    this.MoveCenterPoint(e.currentTarget.dataset.item.location.lng, e.currentTarget.dataset.item.location.lat);
    this.DrawStartPoint(e.currentTarget.dataset.item);
  },

  //控制列表项目的样式的方法，选中后会改变样式
  selectStyleControll(e){
    if (this.data.currentBtn == e.currentTarget.dataset.index) {
      // 再点一下 取消选中
      this.setData({
        currentBtn: -1
      })
    } else {
      this.setData({
        currentBtn: e.currentTarget.dataset.index
      })
    }
  },


  /*************************************
   *标签 终点输入框的相关监听函数设置********* TAG LISTEN END
   * ***********************************
   */

//点击终点输入框
tapEndInputBar: function(e){
  this.EndGetFocus();
},
//终点输入框需要进入“聚焦”状态时，调用该方法
EndGetFocus(){
  this.ConfirmDisplay_END();
  this.LocationListDisplay_END();

  // 设置当前焦点
  this.setData({
    what_is_focused: 2
  });
},
//终点输入框需要进入“失焦”状态时，调用该方法
EndLoseFocus(){
  this.ConfirmDissappear_END();
  this.LocationListDissappear_END();

  //设置失去焦点
  this.setData({
    what_is_focused: -1
  });
},

//输入终点输入框
endSearchInput(e){
    let val = e.detail.value;
    console.log("[INFO]--终点输入框的值：",val);
    if(e.detail.value == ''){
      //当输入框的值为空的时候，这里应该做的是，清空输入框，然后播放清除
      this.clearInput_END();
    }else{
      //设置输入框的内容到全局
      this.setData({
        searchData_END:e.detail.value,
        keyword_END:e.detail.value,
        clear_END:true,
        currentBtn_END:-1//恢复默认未选中
      });
   
      //发送请求
      // 先清空一下locationList，然后再请求地点建议
      this.setData({locationList_END:[]});
      this.Suggestion_Debounce_END(this);
      
      console.log("[INFO]LocationSuggestion_END:",this.data.locationList);
    }
    //列表动画播放
    this.LocationListDisplay_END();
},
//终点输入框点击确认图片
confirm_end(){
  console.log("[LISTEN] -- 终点确认")
  this.EndLoseFocus();
},
//终点输入框聚焦
endFocus(e){
  this.EndGetFocus();
},
//终点输入框失去焦点
endBlur(e){

},
//========================================输入框项目点击监听函数 TAG LISTEN END LIST
tapListItem_END(e){
  this.selectStyleControll_END(e);//控制点击之后的项目的样式
  let data = e.currentTarget.dataset.item;
  this.setData({
    end_point:data,
    searchData_END:data.title,
  });

  //移动地图，让地图包括显示起点和终点
  this.MoveCenterPoint(e.currentTarget.dataset.item.location.lng, e.currentTarget.dataset.item.location.lat);
  //绘制终点的图标
  this.DrawEndPoint(data);

},
//控制列表项目的样式的方法，选中后会改变样式
selectStyleControll_END(e){
  if (this.data.currentBtn_END == e.currentTarget.dataset.index) {
    // // 再点一下 取消选中
    // this.setData({
    //   currentBtn_END: -1
    // })
    //取消选中没意义, 二次点击功能直接废掉算了
    return ;
  } else {
    this.setData({
      currentBtn_END: e.currentTarget.dataset.index
    })
  }
},
//终点列表滑动到底部时触发的方法，
scroll_to_bottom_END(e){
  if(this.data.locationList.length == 0){//这个判断是用来防止BUG的
    console.log("locationlist中没有数据，不需要请求下一页")
    return ;
  }
  console.log("滚动到底部了，请求新的数据，keyword_end:",this.data.keyword_END);
  let count = this.data.count_END;
  let page_size = this.data.page_size_END;
  let pageNum = count%page_size == 0? (count/page_size) : (count/page_size + 1);

  if(this.data.page_size < pageNum){//如果不是最底部的一页，那就发送请求，请求数据
    this.setData({
      page_index_END:this.data.page_index_END +1
    });
    this.Suggestion_Debounce_END(this);
  }else{
    console.log("当前关键词的所有数据已经全部展示了，再往下滑也没有数据了")
  }
},

/**
 * 地图监听函数 TAG LISTEN MAP
 */

 //点击地图上marker的监听函数，TAG LISTEN MAP MARKER
markertap:function(e){
  
  let tap_marker_id = e.detail.markerId;
  let markerArray = this.data.markers;
  if(tap_marker_id == 1001){//控制起点的Marker标签消失
    console.log("[LISTEN][MARKER] -- 起点Marker")
    markerArray.forEach((currentValue,index)=>{
      if(currentValue.id == 1001){
          if(currentValue.label.content==''){//标签没有显示的时候就显示标签
            let key = 'markers['+ index +'].label.content'
            this.setData({
              [key]: this.data.start_point.title
            });
          }else{//标签有显示的时候就隐藏标签
            let key = 'markers['+ index +'].label.content'
            this.setData({
              [key]: ''
            });
          }
      }
    });
  }
  if(tap_marker_id == 1002){//控制终点的Marker标签消失
    console.log("[LISTEN][MARKER] -- 终点Marker")
    markerArray.forEach((currentValue,index)=>{
      if(currentValue.id == 1002){
        if(currentValue.label.content==''){//标签没有显示的时候就显示标签
          let key = 'markers['+ index +'].label.content'
          this.setData({
            [key]: this.data.end_point.title
          });
        }else{//标签有显示的时候就隐藏标签
          let key = 'markers['+ index +'].label.content'
          this.setData({
            [key]: ''
          });
        }
      }
    });
  }
},

// 地图遮罩层的监听函数
tapMapCover:function(e){
  console.log("[LISTEN][MAP] -- 点击地图遮罩层");
  if(this.data.what_is_focused == 1){//控制起点输入框失去焦点
    this.StartLoseFocus();
  }
  if(this.data.what_is_focused == 2){//控制终点输入框失去焦点
    this.EndLoseFocus();
  }
},


/*************************
 *标签 终点输入框相关动画 TAG ANIMATE END
 * ************************
 */
//确认按钮的显示动画
ConfirmDisplay_END(){
  this.setData({
    className_END:'confirm_btn_appear',
    cover_end:true,
  });
},
//确认按钮的消失动画
ConfirmDissappear_END(){
  this.setData({
    className_END:'confirm_btn_disappear',
    cover_end:false,
  })
},
//遮罩层的监听函数
OntapEndcover(){
  //设置遮罩层消失
  this.setData({
    className_END: 'confirm_btn_disappear',
    cover_end:false
  });
  //设置展开列表消失
  this.LocationListDissappear_END();
},
//终点列表的展开控制动画
LocationListDisplay_END(){
  let that = this;
  let height = this.data.list_height_END;//整个列表的当前高度
  let item_height = this.data.item_height_END;//单个项目的高度
  let during = this.data.list_during;//动画播放速度
  let list_expand_height = this.data.list_expand_height_END; //列表展开高度

  if(height == list_expand_height && this.data.locationList_END.length ==0){//这个是多项变成一项的时候的动画
    this.animate(".location_list_end",[{
      height:list_expand_height
    },{
      height:item_height
    }],during,function(){
      that.clearAnimation(".location_list_end",()=>{that.setData({list_height_END:item_height})});
    });
  }

  if(height == '0rpx' && this.data.locationList_END.length == 0){//这个是播放列表出现动画,地点列表中没有数据的时候，列表高度只为一项
    this.animate(".location_list_end",[{
      height:'0rpx'
    },{
      height:item_height
    }],during,function(){
      that.clearAnimation(".location_list_end",()=>{that.setData({list_height_END:item_height})});
    });
  }

  if(height == item_height && this.data.locationList_END.length != 0){//这个是播放列表由一项展开到多项时的动画
    that.animate(".location_list_end",[{
      height:item_height
    },{
      height:list_expand_height
    }],during,function(){
      that.clearAnimation(".location_list_end",()=>{that.setData({list_height_END:list_expand_height})});
    });
  }

  if(height == '0rpx' && this.data.locationList_END.length != 0){//这个是由消失到出现的动画，0rpx到20vh
    that.animate(".location_list_end",[{
      height:'0rpx'
    },{
      height:list_expand_height
    }],during,function(){
      that.clearAnimation(".location_list_end",()=>{that.setData({list_height_END:list_expand_height})});
    });
  }

  if(height == list_expand_height){//由0rpx到60rpx，或者由60rpx到20vh时播放动画， 如果是height是20vh到20vh，就不播放动画了。
    return ;//这个return有点危险
  }
},
//终点列表消失动画
LocationListDissappear_END(){
  let that = this;
  let height = this.data.list_height_END;
  let item_height = this.data.item_height_END;
  let during = this.data.list_during;
  let list_expand_height = this.data.list_expand_height_END;

  if(height == item_height ){//单项时的消失动画
    this.animate(".location_list_end",[
      {
        height: item_height
      },
      {
        height:'0rpx'
      }
    ],during,function(){
      that.clearAnimation(".location_list_end",()=>{
        that.setData({list_height_END:'0rpx'});
      })
    });
  }

  if(height == list_expand_height){//列表展开时的消失动画
    this.animate(".location_list_end",[
      {
        height: list_expand_height
      },
      {
        height:'0rpx'
      }
    ],during,function(){
      that.clearAnimation(".location_list_end",()=>{
        that.setData({list_height_END:'0rpx'});
      })
    });
  }
},

//清空终点输入框 TAG LISTEN INPUT CLEAR END
clearInput_END(){
  this.setData({
    clear_END:false,//输入框相关数据的清空
    searchData_END:'',
    keyword_END:'',
    currentBtn_END:-1,//列表选项样式的清空

    locationList_END:[],//地点建议列表的清空
    page_index_END:1,//建议的初试页面恢复到第一页

    end_point_marker:[],//清空终点的Marker
    end_point:{},//清空终点相关信息

    polyline_route:[],//清空掉地图的总polyline
    polyline_part:[],//清空掉地图的part_polyline

    routes:[],//清空掉路线信息
    currentBtn_PLAN:0,//左边的方案恢复默认
    currentBtn_STEP: -1 ,//步骤选择，样式复原
    currentBtn_STEP_2: -1,
    geton_getoff:[],
  });
  this.refreshMarker();//刷新界面
  this.refreshPolyline();
},
/***********************************************************************************
 *标签 地图顶部控制栏的监听函数 方案出行列表的选择**********************************************************
 * *********************************************************************************
 */
//TAG LISTEN SELECT
//切换出行方式的监听函数
tapSelectList(e){
  this.listItemStyleControll(e);
  console.log("当前选择的出行方式:",e.currentTarget.dataset.index);

},

//处理选中的样式
listItemStyleControll(e){
  if(e.currentTarget.dataset.index == this.data.currentBtn_SELECT){
    //点击已经选中的项目，可以在此处设置二次触发的事件
    return ;
  }else{
    //切换出行方式时触发的，
    
    this.setData({//首先先完成切换的样式控制。
      currentBtn_SELECT: e.currentTarget.dataset.index,
      transX: this.data.item_width*e.currentTarget.dataset.index,

      //然后清楚掉步骤的选中，以及将scroll-view回归顶部, 方案选择也回归到第一个
      currentBtn_STEP: -1,
      scroll_top_STEP: 0,
      currentBtn_PLAN: 0,
      currentBtn_STEP_2:-1,
      //地图上有的polyline也要清除掉
      part_polyline:[],
      geton_getoff:[],//公交线路出入站点也要清空
    });

    //然后发起相应的出行方式的路线规划的请求
    console.log("[LISTEN][SELECT] -- 切换出行方案，重新请求路线数据"+e.currentTarget.dataset.index);
    let from_point = this.data.start_point.location.lat+","+this.data.start_point.location.lng
    let end_point = this.data.end_point.location.lat+","+this.data.end_point.location.lng;
    this.getRoutePlan(from_point,end_point);
  }
},

//二级方案选项的触发函数TAG LISTEN SELECT SWITCH_PLAN
tapRouteItem:function(e){
  console.log("[INFO] -- 当前选择的出行方式:",e.currentTarget.dataset.index);
  if(e.currentTarget.dataset.index == this.data.currentBtn_PLAN){
    //二次点击，控制右边的步骤列表，滚动回顶部, 以及取消选中的步骤项目
    this.setData({
      scroll_top_STEP: 0,//设置滚动回顶部，然后清空掉选中的项。
      currentBtn_STEP: -1,//一级步骤清空
      currentBtn_STEP_2: -1,//二级步骤清空
    });
    //polyline_part，也要刷新一下
    this.setData({
      polyline_part: []
    });
    this.refreshPolyline();

    //重新聚焦到整个路线
    this.map_focus_forRoutes(this.data.polyline_route[0].points);

    return ;
  }else{
    //更新下标，详情页的数据是根据下标生成的，这样应该会更新界面吧
    this.setData({
      currentBtn_PLAN: e.currentTarget.dataset.index,
      currentBtn_STEP: -1, //既然切换了方案，那么当然要取消选中，详情页中的已经选中了的项目
      scroll_top_STEP: 0, //设置滚动回到顶部

      //公交路线的二级步骤也清除掉
      currentBtn_STEP_2: -1
    });
    //清空掉polyline_part，并且刷新界面
    this.setData({
      polyline_part: []
    });

    //更换主polyline
    this.drawThreeRoute(e.currentTarget.dataset.index);
    
    // this.refreshMarker()
    //重新聚焦地图（整个路线），polyline_route是存储当前地图显示的polyline的，所以使用这个数据聚焦估计也是没有问题
    this.map_focus_forRoutes(this.data.polyline_route[0].points);

  }
},
//由于公交的数据特殊，切换方案的函数也要特殊准备
tapRouteItem_BUS(e){
  
  console.log("[INFO] -- 当前选择的方案:",e.currentTarget.dataset.index);
  if(e.currentTarget.dataset.index == this.data.currentBtn_PLAN){
    //二次点击，控制右边的步骤列表，滚动回顶部, 以及取消选中的步骤项目
    this.setData({
      scroll_top_STEP: 0,//设置滚动回顶部，然后清空掉选中的项。
      currentBtn_STEP: -1,
    });
    //polyline_part，也要刷新一下
    // this.setData({
    //   polyline_part: []
    // });
    // this.refreshPolyline();

    //重新聚焦到整个路线
    // this.map_focus_forRoutes(this.data.polyline_route[0].points);

    return ;
  }else{
    //更新下标，详情页的数据是根据下标生成的，这样应该会更新界面吧
    this.setData({
      currentBtn_PLAN: e.currentTarget.dataset.index,
      currentBtn_STEP: -1, //既然切换了方案，那么当然要取消选中，详情页中的已经选中了的项目
      scroll_top_STEP: 0, //设置滚动回到顶部
    });
    //清空掉polyline_part，并且刷新界面
    // this.setData({
    //   polyline_part: []
    // });

    //更换主polyline
    this.drawThreeRoute_ForBUS(e.currentTarget.dataset.index);
    //重新聚焦地图
    let points = []
    for(let i=0;i<this.data.polyline_route.length;i++){
      points = points.concat(this.data.polyline_route[i].points);
    }
    this.map_focus_forRoutes(points);
  }
},



//出行步骤的点击监听方法 TAG LISTEN SELECT STEP
tapStep:function(e){
  this.StepStyleControll(e);
  //点击之后绘制一段polyline，移动地图然后聚焦, 然后再播放一下动画
},
//出行步骤的样式控制
StepStyleControll(e){
  if(e.currentTarget.dataset.index == this.data.currentBtn_STEP){
    //二次点击时将样式还原
   this.setData({
     currentBtn_STEP:-1,
     polyline_part:[],
   });
   //刷新polyline
   this.refreshPolyline();
   
  }else{
    this.setData({
      currentBtn_STEP: e.currentTarget.dataset.index
    });

  //绘制polyline
  let from = e.currentTarget.dataset.step.polyline_idx[0];
  let to = e.currentTarget.dataset.step.polyline_idx[1];
  this.drawPartPolyine(this.data.routes[this.data.currentBtn_PLAN].polyline,from,to);
  //移动地图聚焦到该部分路段
  this.map_focus_forPart(this.data.polyline_part.points);
  }
},

//TAG LISTEN STEP
//控制公交步骤的项目的监听函数，要根据不同的出行类型，进行不同的操作
//一级的STEP控制，这个一级的step数据要保存下来，因为二级的要用到（具体是一级的polyline需要用到）
tapStep_PUBLIC:function(e){
  //样式控制
  if(e.currentTarget.dataset.index == this.data.currentBtn_STEP){//二次点击步骤
    this.setData({
      currentBtn_STEP:-1,
      polyline_part:[],//清空掉当前地图上的polyline
    });
    return ;
  }else{//切换步骤, 
    this.setData({
      currentBtn_STEP: e.currentTarget.dataset.index, // 一级步骤的下标,
      //此时二级步骤的下标要清空掉，polyline_part也是
      currentBtn_STEP_2: -1,
      polyline_part: [],
    });
    this.refreshPolyline();

    if(e.currentTarget.dataset.step.mode == "WALKING"){
      this.setData({
        currentPolyline_STEP_1: e.currentTarget.dataset.step.polyline,//一级下标对应的polyline，二级步骤要用到。这个数据只有WALKING能用，其他的数据是直接放在二级步骤中的，没有分离。
      });
    }

    //绘制部分polyline，以及相关站点Marker
    console.log("[LISTEN][STEP] -- 当前步骤：",e.currentTarget.dataset.step);

    //不同出行方式的不同处理方式，不过这些处理方式大差不差，都是绘制polyline，聚焦，有的可能还要多绘制几个起点终点marker
    if(e.currentTarget.dataset.step.mode == "WALKING"){
      this.WALKING_resolve(e);
    }
    if(e.currentTarget.dataset.step.mode == "TRANSIT"){
      if(e.currentTarget.dataset.step.lines[0].vehicle == "SUBWAY"){
        this.SUBWAY_resolve(e);
      }
      if(e.currentTarget.dataset.step.lines[0].vehicle == "BUS"){
        this.BUS_resolve(e);
      }
      if(e.currentTarget.dataset.step.lines[0].vehicle == "RAIL"){
        this.RAIL_resolve(e);
      }
    }
  }
},

//处理函数，主要就是绘制部分polyline，如果有Marker的话，绘制一下,而且我觉得大部分的polyline都不用绘制了，因为一开始就已经设置了不同的颜色
WALKING_resolve(e){
  //直接聚焦行了，一般WALKING不会连续出现，辨识度很高，不用特殊绘制一根曲线
  let points = this.data.polyline_BUS_collection[this.data.currentBtn_STEP].points;
  this.map_focus_forRoutes(points);
},
SUBWAY_resolve(e){


//直接聚焦，地铁的话感觉绘制一条线条比较好，不过绘制线条还是放在二级步骤中实现
  let points = this.data.polyline_BUS_collection_change[this.data.currentBtn_STEP][0].points;
  this.map_focus_forRoutes(points);
},
BUS_resolve(e){
  //这个公交的，感觉也是直接聚焦第一条公交路线算了，描绘出来也没有用，二级步骤负责切换功能
  // e.currentTarget.dataset.step.lines[0]
  let points = this.data.polyline_BUS_collection[this.data.currentBtn_STEP][0].points;
  this.map_focus_forPart(points);
},
RAIL_resolve(e){
  let points = this.data.polyline_BUS_collection[this.data.currentBtn_STEP][0].points;
  this.map_focus_forPart(points);
},
//行走时的步骤选项,相当于二级选项，WALKING二级 TAG LISTEN STEP WALKING
WALKING_tap:function(e){
  console.log("[LISTEN][WALKING_tap] -- ",e);
  if(this.data.currentBtn_STEP == -1){ //如果上一级的步骤没有被选中，这个二级步骤不准选中
    return ;
  }

  //控制样式
  if(e.currentTarget.dataset.index == this.data.currentBtn_STEP_2){
    this.setData({
      currentBtn_STEP_2: -1,//清除样式
      polyline_part:[],//清除部分polyline
    });
    this.refreshPolyline();//刷新界面
    return ;
  }else{
    this.setData({
      currentBtn_STEP_2: e.currentTarget.dataset.index//设置当前选中的二级步骤坐标，在绘制部分polyline的时候应该有用
    });
    //绘制对应的polyline
    let from = e.currentTarget.dataset.step.polyline_idx[0];
    let to = e.currentTarget.dataset.step.polyline_idx[1];
    this.drawPartPolyine(this.data.currentPolyline_STEP_1, from, to);
    //聚焦
    this.map_focus_forPart(this.data.polyline_part.points);
  }
  
},
//BUS的二级步骤控制
BUS_tap:function(e){
  //如果未选中一级STEP，禁止触发二级
  console.log("[LISTEN][BUS_tap] -- ",e);
  if(this.data.currentBtn_STEP == -1){
    return ;
  }
  //样式控制
  if(this.data.currentBtn_STEP_2 == e.currentTarget.dataset.index){
    this.setData({
      currentBtn_STEP_2: -1,
      geton_getoff:[],//清空掉入站出站的Marker
    })
    this.refreshMarker();
  }else{//切换公交线路
    this.setData({
      currentBtn_STEP_2: e.currentTarget.dataset.index,
      geton_getoff:[],
    });

    //切换主公交路线，这个是个艰巨的任务，要先将该二级步骤下的所有路线颜色绘制为light，然后再进行绘制deep
    //先定位到目前选择的二级步骤的下标
    let idx1 = this.data.currentBtn_STEP;
    let idx2 = this.data.currentBtn_STEP_2;
    console.log("[LISTEN][BUS_tap] -- idx1, idx2 ",idx1,idx2)
    console.log("[LISTEN][BUS_tap] 控制当前界面polyline_route数据的数组 -- ",this.data.polyline_BUS_collection_change[idx1][idx2]);

    //先将该二级步骤下的所有线路绘制成light的颜色
    for(let i=0;i<this.data.polyline_BUS_collection_change[idx1].length;i++){
      this.changeBUSpolyline(idx1,i,this.data.color_polyline.bus_light);
    }
  
    // 调用函数修改掉显示的数组 polyline_BUS_colleciton_change
    this.changeBUSpolyline(idx1,idx2,this.data.color_polyline.bus_deep);

    //重新解析显示数组，制作成polyline_route
    this.parseBusPolyline(this.data.polyline_BUS_collection_change);

    //刷新整个polyline
    this.refreshPolyline();

    //==到Marker环节，
    let getOnPoint = {
      longitude: e.currentTarget.dataset.line.geton.location.lng,
      latitude: e.currentTarget.dataset.line.geton.location.lat
    }
    let getOffPoint = {
      longitude: e.currentTarget.dataset.line.getoff.location.lng,
      latitude: e.currentTarget.dataset.line.getoff.location.lat
    }
    let getonTitle = e.currentTarget.dataset.line.geton.title;
    let getOffTitle = e.currentTarget.dataset.line.getoff.title;
    //该方法自带刷新，直接调用即可
    this.Draw_GetOnOff_Marker(getOnPoint,getOffPoint,getonTitle,getOffTitle);
  }
},
//地铁的二级步骤监听函数
SUBWAY_tap:function(e){
  //因为地铁推荐线路一般只有一条，所以就不采用点击其他线路切换颜色的方式了，采用绘制polyline的方式
  //如果未选中一级STEP，禁止触发二级
  console.log("[LISTEN][SUBWAY_tap] -- ",e);
  if(this.data.currentBtn_STEP == -1){
    return ;
  }
  if(this.data.currentBtn_STEP_2 == e.currentTarget.dataset.index){
    this.setData({
      currentBtn_STEP_2: -1,
      polyline_part:[],
      geton_getoff:[],
    });
    this.refreshPolyline();
    this.refreshMarker();
  }else{
    this.setData({
      currentBtn_STEP_2: e.currentTarget.dataset.index,
      polyline_part:[],//切换时清空部分polyline
      geton_getoff:[],
    });


    //绘制polyline
    let polyline_subway = e.currentTarget.dataset.line.polyline;
    this.drawPartPolyine(polyline_subway, 0, polyline_subway.length);

    //绘制好后聚焦
    this.map_focus_forPart(this.data.polyline_part);

    //== MARKER部分
    let getOnPoint = {
      longitude: e.currentTarget.dataset.line.geton.location.lng,
      latitude: e.currentTarget.dataset.line.geton.location.lat
    }
    let getOffPoint = {
      longitude: e.currentTarget.dataset.line.getoff.location.lng,
      latitude: e.currentTarget.dataset.line.getoff.location.lat
    }
    let getonTitle = e.currentTarget.dataset.line.geton.title;
    let getOffTitle = e.currentTarget.dataset.line.getoff.title;
    //该方法自带刷新，直接调用即可
    this.Draw_GetOnOff_Marker(getOnPoint,getOffPoint,getonTitle,getOffTitle);
  }

},
RAIL_tap:function(e){
  console.log("[LISTEN][RAIL_tap] -- ",e);
  if(this.data.currentBtn_STEP == -1){
    return ;
  } 
  if(this.data.currentBtn_STEP_2 == e.currentTarget.dataset.index){
    this.setData({
      currentBtn_STEP_2: -1,
      polyline_part:[],
      geton_getoff:[],
    });
    this.refreshPolyline();
    this.refreshMarker();
  }else{
    this.setData({
      currentBtn_STEP_2: e.currentTarget.dataset.index,
      polyline_part:[],//切换时清空部分polyline
      geton_getoff: [],
    });


    //绘制polyline
    let polyline = e.currentTarget.dataset.line.polyline;
    this.drawPartPolyine(polyline, 0, polyline.length);

    //绘制好后聚焦
    this.map_focus_forPart(this.data.polyline_part);

     //== MARKER部分
     let getOnPoint = {
      longitude: e.currentTarget.dataset.line.geton.location.lng,
      latitude: e.currentTarget.dataset.line.geton.location.lat
    }
    let getOffPoint = {
      longitude: e.currentTarget.dataset.line.getoff.location.lng,
      latitude: e.currentTarget.dataset.line.getoff.location.lat
    }
    let getonTitle = e.currentTarget.dataset.line.geton.title;
    let getOffTitle = e.currentTarget.dataset.line.getoff.title;
    //该方法自带刷新，直接调用即可
    this.Draw_GetOnOff_Marker(getOnPoint,getOffPoint,getonTitle,getOffTitle);
  }

},


/**
 * 地图内部组件的相关监听方法
 * TAG LISTEN POSITION
 */
//右下角定位图标的监听函数
showPositioning:function(e){
  if(this.data.isShowPositioning == true){//收缩
    this.setData({
      isShowPositioning: false,
      end_class: 'end_fold',
      start_clas: 'start_fold',
      rocker_class: 'rocker_fold'
    });
  }else{//展开
    this.setData({
      isShowPositioning: true,
      end_class: 'end_expand',
      start_clas:'start_expand',
      rocker_class: 'rocker_expand',
    });
  }
},
//地图拖动时触发的方法
regionchange(e){
  //只有展开按钮时才能调用
  if(this.data.isShowPositioning == false){
    return ;
  }
  console.log("[MAPCHANGEG]--",e)
  if(e.type == "end"){
    console.log("[MAPCHANGE] -- 当前地图中心经纬度：",e.detail.centerLocation)

    //将当前经纬度保存起来，如果用户点击起点或者终点，那就将当前经纬度得到的地址发起请求。。
    this.setData({
      center_longitude: (e.detail.centerLocation.longitude).toFixed(6),
      center_latitude: (e.detail.centerLocation.latitude).toFixed(6)
    });

    //发送请求,进行逆地址解析
    this.Geocoder(this);

  }
},
setEnd(e){
  console.log("[LISTEN][setEnd]")
  if(JSON.stringify(this.data.center_point) == "{}"){
    wx.showToast({
      title: '解析地址不能使用',
    });
  }

  let end_point_fake = this.data.center_point;
  this.setData({
    end_point: end_point_fake,
    searchData_END: end_point_fake.title,
  });
  console.log("[LISTEN][setEND] -- 执行MoveCenterPoint")
  //移动到相应点位，然后绘制起点
  this.MoveCenterPoint(end_point_fake.location.lng, end_point_fake.location.lat);
  this.DrawEndPoint(end_point_fake);
},
setStart(e){
  console.log("[LISTEN][setStart]")
  if(JSON.stringify(this.data.center_point) == "{}"){
    wx.showToast({
      title: '解析地址为空',
    });
    return ;
  }
  //如果逆地址成功构造出一个假点的话，就用这个假点设置起点
  let start_point_fake = this.data.center_point;
  this.setData({
    start_point: start_point_fake, //假点也是很多地方要用到的
    searchData: start_point_fake.title,//把假点的标题放进输入框，假装是搜索出来的哈哈哈哈
  })
  console.log("[LISTEN][setStart]--执行MoveCenterPoint")
  //移动到相应点位，然后绘制起点
  this.MoveCenterPoint(start_point_fake.location.lng, start_point_fake.location.lat);
  this.DrawStartPoint(start_point_fake);
},

//触发这个方法之后，就直接使用微信内置的导航....谁叫你不会做实时导航啊。。。
GoPositioning:function(e){
  if(this.data.center_longitude==-1 || this.data.center_latitude == -1){
    wx.showToast({
      title: '请先选中一个点',
    });
    return ;
  }
  wx.openLocation({
    latitude: Number(this.data.center_latitude),
    longitude: Number(this.data.center_longitude),
  })
},

/**********************
 *标签 地图控制栏的监听函数 TAG LISTEN MAP BAR
 * **********************
 */
tapMapBar:function(e){
  //添加一个判断，要有路线数据的时候才可以点击
  if(this.data.routes.length == 0 ){
    wx.showToast({
      title: '输入地点后展开',
      icon:'none'
    })
    return ;
  }

  if(this.data.mapbar == -1){
    console.log("[LISTEN][MAP] -- Expand,方案详情展开");
    //地图高度降低
    this.setData({
      map_className:'Map_origin_expand',
      mapbar: 1,
      search_box: 'search-box_up',//切换输入框的样式，使其上升隐藏
      route_detail: 'route_detail_up',//控制路线详情的框向上移动，这个动画原本是可以不添加的，但是因为这个层级居然是比输入框层级高的，并且输入框的层级没办法去覆盖这个东西。。。所以以后写界面，一定一定要有一个统一的父组件，不然z-index根本没用
    });
  }else{
    //恢复地图的高度
    console.log("[LISTEN][MAP] -- Fold,方案详情收缩");
    this.setData({
      map_className:'Map_origin_fold',
      mapbar:-1,
      search_box: 'search-box_down',//使输入框下移，恢复其本来的样式
      route_detail: 'route_detail_down',//控制方案详情列表向下移动。
    });
  }
},
//地图动画播放完毕之后的监听函数
mapAnimationEnd:function(e){
  console.log("地图动画播放完毕",e);
  console.log("地图动画"+e.detail.animationName+"播放完毕")
  let animate = e.detail.animationName;
  if(animate == 'mapExpand'){
    //进入到展开状态，播放箭头旋转向上的动画
    this.setData({
      mapBar_className:'map_bar_img_up',
    });
    //同时控制地图中心显示起点和终点的位置。
  }
  if(animate == 'mapFold'){
    //进入到折叠状态，播放箭头旋转向下的动画
    this.setData({
      mapBar_className:'map_bar_img_down',
    });
  }
},

/*************************
 *标签 *** 地图控制相关函数**** TAG MAP
 * ***********************
 */
//刷新地图Marker的方法
refreshMarker(){
  //先清空
  this.setData({
    markers:[]
  });
  let startPointMarker = this.data.start_point_marker;
  let endPointMarker = this.data.end_point_marker;
  let geton_getoff = this.data.geton_getoff;
  let total = startPointMarker.concat(endPointMarker).concat(geton_getoff);
  this.setData({
    markers:total
  })
},

//将地图中心移动的函数, 地图中心移动的同时，也请求路线信息？
MoveCenterPoint(lng,lat){
  //先判断一下，有没有起点终点信息，如果都有，那就使用include，如果没有，或者只有一个点的数据，就直接使用中心点数据
  if(JSON.stringify(this.data.start_point)!="{}" && JSON.stringify(this.data.end_point)!="{}"){
    console.log("[INFO] -- start_point:"+this.data.start_point+"，end_point:"+this.data.end_point);
    let pointArr = [];
    let startpoint = {
      longitude:this.data.start_point.location.lng,
      latitude:this.data.start_point.location.lat
    }
    let endpoint = {
      longitude: this.data.end_point.location.lng,
      latitude: this.data.end_point.location.lat
    }
    //由于includePoint有巨大误差，终点和起点并不能完全包括在屏幕内，所以就用几个假点，来让includePoint扩大范围
    pointArr.push(startpoint);
    pointArr.push(endpoint);
    let fakePoint1 = {
      longitude: this.data.end_point.location.lng + 0.01,
      latitude: this.data.end_point.location.lat+ 0.01
    }
    let fakePoint2 = {
      longitude: this.data.start_point.location.lng - 0.01,
      latitude: this.data.start_point.location.lat- 0.01
    }
    pointArr.push(fakePoint1);
    pointArr.push(fakePoint2);
    let mapContext = wx.createMapContext('Map');
    mapContext.includePoints({
      points:pointArr,
      padding:[100,100,100,100]
      // success:function(){} //移动成功之后的回调参数
    });

    
    //调用路线规划 TAG MAP ROUTE
    
    let from_point = String(startpoint.latitude) + "," + String(startpoint.longitude);
    let end_point = String(endpoint.latitude) + "," + String(endpoint.longitude);
    console.log("[INFO][MAP][ROUTE] -- 发起路线规划请求：起点坐标["+from_point+"]"+"，终点坐标：["+end_point+"]"+"出行方式："+this.data.currentBtn_SELECT);
    this.getRoutePlan(from_point,end_point);


  }else{//只有一个点的时候，直接设置经纬度
    this.setData({
      longitude:lng,
      latitude:lat,
    })
  }

},

//控制地图聚焦的方法，和上面的移动地图中心差不多，但是因为上面的地图移动是绑定了数据请求的，所以还是不要轻易使用上面的方法了
//这个聚焦函数是专门为步骤显示制作的
map_focus_forPart(points){
  let mapContext = wx.createMapContext('Map');
  mapContext.includePoints({
    points:points,
    padding:[50,50,50,50]
    // success:function(){}// 这个函数留着，如果无聊，想做小车动画的话，可以在这里放置小车动画
  })
},
//这个聚焦函数是专门用来聚焦路线的，只要route不为空即可以调用
map_focus_forRoutes(points){
  let mapContext = wx.createMapContext('Map');
  mapContext.includePoints({
    points:points,
    padding:[80,80,80,80]
  })
},
//这个函数是专门用来聚焦起点和终点的，要起点和终点同时存在时调用
map_focus_forPoint(){
  let mapContext = wx.createMapContext('Map');
  let pointArrs = [];
  let fakePoint1 = {longitude: this.data.end_point.location.lng + 0.01,latitude: this.data.end_point.location.lat+ 0.01}
  let fakePoint2 = {longitude: this.data.start_point.location.lng - 0.01,latitude: this.data.start_point.location.lat- 0.01}
  console.log("================================",pointArrs)
  pointArrs.push(fakePoint1,fakePoint2);
  mapContext.includePoints({
    points:pointArrs
    // padding:[80,80,80,80]
  });
},

//绘制起点的坐标
DrawStartPoint(item){
  this.setData({//先清空掉之前的数据
    start_point_marker:[]
  })
  let startMarker = {
    id: 1001,
    iconPath: "../../images/start.png",
    longitude: item.location.lng,
    latitude: item.location.lat,
    width: 60,
    height: 60,
    zIndex: 1000,
    label:{
      content:item.title,
      color:'#002329',
      fontSize:12,
      borderWidth:4,
      borderColor:'#10239e',
      borderRadius:8,
      bgColor:'#e6f7ff',
      padding:4,
      textAlign:"center",
      // anchorX:'',//偏移量
      // anchorY:''
    }
  };
  let arr = [];
  arr.push(startMarker);
  this.setData({
    start_point_marker:arr,
  });
  this.refreshMarker();
},
//绘制终点坐标
DrawEndPoint(item){
  this.setData({//先清空掉之前的数据
    end_point_marker:[]
  })
  let endpointMarker = {
    id: 1002,
    iconPath: "../../images/end.png",
    longitude: item.location.lng,
    latitude: item.location.lat,
    width: 60,
    height: 60,
    zIndex: 1000,
    label:{
      content:item.title,
      color:'#002329',
      fontSize:12,
      borderWidth:4,
      borderColor:'#10239e',
      borderRadius:8,
      bgColor:'#e6f7ff',
      padding:4,
      textAlign:"center",
      // anchorX:'',//偏移量
      // anchorY:''
    }
  };
  let arr = [];
  arr.push(endpointMarker);
  this.setData({
    end_point_marker:arr,
  });
  this.refreshMarker();

},

//绘制进站点和出站点的Marker的函数
Draw_GetOnOff_Marker:function(getOnPoint,getOffPoint,getOnTitle,getOffTitle){
  let getOn = {
    id: 1010,
    iconPath: "../../images/geton.png",
    longitude: getOnPoint.longitude,
    latitude: getOnPoint.latitude,
    width: 30,
    height: 30,
    zIndex: 1000,
    label:{
      content:getOnTitle,
      color:'#002329',
      fontSize:10,
      borderWidth:2,
      borderColor:'#10239e',
      borderRadius:8,
      bgColor:'#e6f7ff',
      padding:4,
      textAlign:"center",
      // anchorX:'',//偏移量
      // anchorY:''
    }
  };
  let getoff = {
    id: 1011,
    iconPath: "../../images/getoff.png",
    longitude: getOffPoint.longitude,
    latitude: getOffPoint.latitude,
    width: 30,
    height: 30,
    zIndex: 1000,
    label:{
      content: getOffTitle,
      color:'#002329',
      fontSize:10,
      borderWidth:2,
      borderColor:'#10239e',
      borderRadius:8,
      bgColor:'#e6f7ff',
      padding:4,
      textAlign:"center",
      // anchorX:'',//偏移量
      // anchorY:''
    }
  };
  
  //先清空一下
  this.setData({
    geton_getoff:[],
  });
  let pointArr = [];
  pointArr.push(getOn);
  pointArr.push(getoff);
  this.setData({
    geton_getoff:pointArr
  });
  //刷新界面
  this.refreshMarker();

},

//TAG MAP POLYLINE
//总的polyline生成，返回的直接是单单一个polyline对象，不是数组
polylineProducer(origin_polyline,linecolor,lineWidth=7){
  //数据两个一组，前纬度，后经度。
  let pointArr = [];
  for(let i=0;i<origin_polyline.length-1;i=i+2){//总觉得这个循环容易出现问题啊
    let point = {
      longitude: origin_polyline[i+1],
      latitude: origin_polyline[i]
    }
    pointArr.push(point);
  }
  //创建polyline
  let polyline = {
    points: pointArr,
    width: lineWidth,
    color: linecolor,
    borderColor: "#ffffff",
    arrowLine: true,
    level:"abovelabels",
  }
  return polyline;
  
},

//制作部分的polyline
drawPartPolyine(origin_polyline, from, to, color="#fab005"){
  //先根据提供的数组索引，取出部分polyline，然后,存到polyline_part 中去，然后刷新？
  let partPoints = origin_polyline.slice(from,to+1)
  let resutl_polyline = this.polylineProducer(partPoints,color,10);

  //没有绘制多部分的polyline的需求，所以直接替换即可
  this.setData({
    polyline_part:resutl_polyline
  });
  //刷新界面
  this.refreshPolyline();
},

//这个函数只是无脑将不同的polyline合在一起
refreshPolyline(){
  //先清空地图上的polyline，然后再塞上新的（其实直接覆盖也行）
  let route_polyline = this.data.polyline_route;
  let part_polyline = this.data.polyline_part;
  this.setData({
    polyline: route_polyline.concat(part_polyline)
  });
},

//修改公交车线路Polyline样式的函数，传入polyline_BUS_collection对应的下标，以及要修改颜色
changeBUSpolyline(idx1,idx2,color){
  //将原始数据深拷贝一份，原来的数据可能在其他地方有用
  // let bus_polyline_data_copy = tool.deepClone(this.data.polyline_BUS_collection);
  let bus_polyline_data = this.data.polyline_BUS_collection_change;
  if(idx2 == null){
    //一级列表在此修改，因为一级列表不会涉及到polyline层级问题，所以直接改显示的数据即可
    bus_polyline_data[idx1].color = color;
  }else{
    //二级列表在此修改，二级列表的修改非常的麻烦，不但要修改元素，还要修改元素在数组中的位置
    
    //深拷贝, 一份要修改的二级数组，将对应元素修改之后，将其覆盖到显示polyline中去。
    // let lines = tool.deepClone(this.data.polyline_BUS_collection[idx1]);
    // let lines = this.data.polyline_BUS_collection[idx1].concat();
    let lines_arr = this.data.polyline_BUS_collection[idx1];
    let lines_arr_deepclone = JSON.parse(JSON.stringify(lines_arr));
    // console.log("[DATA] == 要修改的二级数组数据",lines);
    lines_arr_deepclone[idx2].color = color;
    // //将对应元素沉底，因为显示层级的问题，后面添加的polyline层级是比前面的高的
    lines_arr_deepclone = tool.bottom(idx2,lines_arr_deepclone);

    // //二级数组修改完毕之后， 覆盖掉显示polyline中对应的二级数组=======
    // let str = 'this.data.polyline_BUS_collection_change[' + idx1 +']'
    // this.setData({
    //   [str]:lines_arr_deepclone
    // })
    bus_polyline_data[idx1] = lines_arr_deepclone;

    //这里就不做刷新界面操作了，所以记得调用这个方法之后，要重新parse那个polyline_BUS_change数据，然后refreshPolyline。
    
  }
},

//公交车的线路必须先调用这个才能调用refreshPolyline
parseBusPolyline(polyline_BUS_collection){
  //公交的数据有点特别，一级数组是正常的polyline对象，但是混搭着数组对象，这些数组保存的又是polyline对象。
  //所以需要做的是，将数组对象展开成正常的polyline对象，
  let polyline_bus_concat = [];
  for(let i=0;i<polyline_BUS_collection.length;i++){
    if(Array.isArray(polyline_BUS_collection[i])){//二级数组时，要额外拆开渲染
      for(let j=0;j<polyline_BUS_collection[i].length;j++){
        polyline_bus_concat.push(polyline_BUS_collection[i][j]);
      }
    }else{//一级数组时，直接推进去
      polyline_bus_concat.push(polyline_BUS_collection[i]);
    }
  }
  console.log("[DATA]经过处理之后的公交polyline_route，每段不同的steps都已经分开：",polyline_bus_concat);
  this.setData({
    polyline_route: polyline_bus_concat,
  });
},

//绘制初始的三条路线（因为同时绘制三条路线会导致爆内存，所以只能更改方案了，只绘制一条）
drawThreeRoute(index){
  let routes = this.data.routes
  let main_polyline_Arr = []
  console.log("[DATA]--当前选择的路线",routes[index]);
  let mainRoute = this.polylineProducer(routes[index].polyline,"#389e0d",7);
  main_polyline_Arr.push(mainRoute);

  //直接覆盖掉之前的信息
  this.setData({
    polyline_route: main_polyline_Arr
  });
  //刷新界面
  this.refreshPolyline();
},

//绘制公交的polyline，因为公交车的路线数据非常特别 TAG MAP POLYLINE BUS
drawThreeRoute_ForBUS(index){
  let route = this.data.routes[index];//先选中要绘制的路线
  let polyline_bus_buff = [];//最终的遍历结果
  //先定一下颜色，步行WALKING时，颜色为默认绿色，模型为TRANSIT时，公交与地铁颜色为#a80000，偏棕色，火车的颜色为蓝色#2b88d8？
  for(let i=0;i<route.steps.length;i++){
    if(route.steps[i].mode == "WALKING"){
      let walking_polyline = this.polylineProducer(route.steps[i].polyline,"#389e0d");
      polyline_bus_buff.push(walking_polyline);
    }
    if(route.steps[i].mode == "TRANSIT"){//遍历遇到二维数组的处理方法
      //TRANSIT下级的line一般是有一个，但是也有多个的情况，多个的时候都是备份可选路线，备份可选路线是有可能省略掉信息的。。。。
      let sub_array = [];
      for(let j=0;j<route.steps[i].lines.length;j++){
        if(route.steps[i].lines[0].vehicle == "BUS"){//这里其实有个问题，先绘制的部分，会被后绘制的部分覆盖掉
          let polyline_bus = this.polylineProducer(route.steps[i].lines[j].polyline, this.data.color_polyline.bus_light);
          sub_array.push(polyline_bus);
        }
        if(route.steps[i].lines[0].vehicle == "SUBWAY"){
          let line_color = this.data.color_polyline.subway_light
          let polyline_subway = this.polylineProducer(route.steps[i].lines[j].polyline, line_color);
          sub_array.push(polyline_subway);
        }
        if(route.steps[i].lines[0].vehicle == "RAIL"){
          let line_color = this.data.color_polyline.rail_light;
          let polyline_rail = this.polylineProducer(route.steps[i].lines[j].polyline, line_color);
          sub_array.push(polyline_rail);
        }
      };
      polyline_bus_buff.push(sub_array);
    }
  }

  //公交路线数据处理完毕之后，将其保存，注意这个是二级列表，没办法直接使用
  //这个二级列表保存起来。这个数据是修改地图路线样式的根基
  this.setData({
    polyline_BUS_collection: polyline_bus_buff,
    polyline_BUS_collection_change: JSON.parse(JSON.stringify(polyline_bus_buff)),//这个数据一定要深拷贝，原来setData只是个指针，指向同一块内存区域
  });
  //试用一下更改样式的函数，循环一下， 将有二级列表的样式都修改了
  for(let i=0;i<polyline_bus_buff.length;i++){
    if(Array.isArray(polyline_bus_buff[i])){//只给二级数组设置特殊颜色
      if(polyline_bus_buff[i][0].color == this.data.color_polyline.bus_light){
        this.changeBUSpolyline(i,0,this.data.color_polyline.bus_deep);//把二级数组的第一项的颜色改为深色
      }
      if(polyline_bus_buff[i][0].color == this.data.color_polyline.subway_light){
        this.changeBUSpolyline(i,0,this.data.color_polyline.subway_deep);//把二级数组的第一项的颜色改为深色
      }
      if(polyline_bus_buff[i][0].color == this.data.color_polyline.rail_light){
        this.changeBUSpolyline(i,0,this.data.color_polyline.rail_deep);//把二级数组的第一项的颜色改为深色
      }
    }
  }

  //调用解析方法,将二级列表解析成正常的polyline
  this.parseBusPolyline(this.data.polyline_BUS_collection_change);

  //调用绘制方法，将处理好的数据设置到地图上面
  this.refreshPolyline();

},


  /**********************************************************************************************
   * ********************************************************************************************
   *标签 动画以及布局相关函数区
   * *******************************************************************************************
   */

   /**
    * 起点输入框收缩和确认按钮出现的控制动画
    */
  ConfirmDisplay(){
    //播放动画，输入框变窄，确认按钮出现
  this.setData({
    className: 'confirm_btn_appear',
  //控制下方蒙皮出现，防止用户点击其他控件，并且控制输入框进入到默认状态
    cover_start: true 
  });
  },


  /**
   * 输入框和确认按钮消失的动画
   */
  ConfirmDissappear(){
    this.setData({
      className: 'confirm_btn_disappear',
      cover_start:false
    });
  },

  //设置一个地点搜索列表的动画===
  //这个动画要求是根据locationList的长度，执行不同的动画。
  // 这个是出现动画的设定：
  //1. 长度为0的时候，列表高度动画为60rpx；长度不为0的时候，列表高度动画为20vh。
  //2. 这个动画要求播放的地方：点击输入框时、用户输入字符时。
  // 这个是动画消失的设定:
  //1. 点击输入框之外的地方的时候，即失去焦点的时候，播放列表消失动画，但是数据实际上不会消失，在次聚焦的时候回重新加载
  //2. 点击确认按钮的时候，也是播放列表消失动画，同时执行清空输入框的方法。
  LocationListDisplay(){
    let that = this;
    let height = this.data.list_height;//整个列表的高度
    let item_height = this.data.item_height;//单个项目的高度
    let during = this.data.list_during;//动画播放速度
    let list_expand_height = this.data.list_expand_height; //列表展开高度

    if(height == list_expand_height && this.data.locationList.length ==0){//这个是多项变成一项的时候的动画
      this.animate(".location_list",[{
        height:list_expand_height
      },{
        height:item_height
      }],during,function(){
        that.clearAnimation(".location_list",()=>{that.setData({list_height:item_height})});
      });
    }

    if(height == '0rpx' && this.data.locationList.length == 0){//这个是播放列表出现动画,地点列表中没有数据的时候，列表高度只为一项60rpx
      this.animate(".location_list",[{
        height:'0rpx'
      },{
        height:item_height
      }],during,function(){
        that.clearAnimation(".location_list",()=>{that.setData({list_height:item_height})});
      });
    }

    if(height == item_height && this.data.locationList.length != 0){//这个是播放列表由一项展开到多项时的动画
      that.animate(".location_list",[{
        height:item_height
      },{
        height:list_expand_height
      }],during,function(){
        that.clearAnimation(".location_list",()=>{that.setData({list_height:list_expand_height})});
      });
    }

    if(height == '0rpx' && this.data.locationList.length != 0){//这个是由消失到出现的动画，0rpx到20vh
      that.animate(".location_list",[{
        height:'0rpx'
      },{
        height:list_expand_height
      }],during,function(){
        that.clearAnimation(".location_list",()=>{that.setData({list_height:list_expand_height})});
      });
    }

    if(height == list_expand_height){//由0rpx到60rpx，或者由60rpx到20vh时播放动画， 如果是height是20vh到20vh，就不播放动画了。
      return ;//这个return有点危险
    }
  },

  //列表消失的动画，列表消失有1，失去焦点。2,点击确认按钮。消失情况有两种，一种是60rpx时消失，一种是20vh时消失
  LocationListDissappear(){
    let that = this;
    let height = this.data.list_height;
    let item_height = this.data.item_height;
    let during = this.data.list_during;
    let list_expand_height = this.data.list_expand_height;

    if(height == item_height ){//单项时的消失动画
      this.animate(".location_list",[
        {
          height: item_height
        },
        {
          height:'0rpx'
        }
      ],during,function(){
        that.clearAnimation(".location_list",()=>{
          that.setData({list_height:'0rpx'});
        })
      });
    }

    if(height == list_expand_height){//列表展开时的消失动画
      this.animate(".location_list",[
        {
          height: list_expand_height
        },
        {
          height:'0rpx'
        }
      ],during,function(){
        that.clearAnimation(".location_list",()=>{
          that.setData({list_height:'0rpx'});
        })
      });
    }
  },

  /******************************************************************
   * 其他函数, 如发送请求之类的
   */
  // TAG REQUEST 
  // TAG DRIVE
  getRoutePlan(from,to){
    //根据当前路线方案的下标来决定请求的类型0为驾车，1为步行，3为公共交通
    if(this.data.currentBtn_SELECT == 0){
      let result = tool.getRoutePlan_DRIVE(from,to);
      result.then((res)=>{
        console.log("[INFO][SUCCESS]--腾讯路线规划DRIVE",res);
        //将路线信息保存起来
        this.setData({
          routes: res.data.result.routes
        });

        //路线信息保存好之后，调用地图的polyline绘制函数。默认绘制第一条
        this.drawThreeRoute(0);
        
    }).catch((err)=>{console.log("[ERROR]--路线规划请求出错",err)})
    }

    //请求步行路线规划
    if(this.data.currentBtn_SELECT == 1){
      let request = tool.getRoutePlan_WALKING(from,to);
      request.then((res)=>{
        console.log("[INFO][SUCCESS]--腾讯路线规划WALKING",res);
        //将路线信息保存起来
        this.setData({
          routes: res.data.result.routes
        });

        //调用绘制路线方法
        this.drawThreeRoute(0);

      }).catch((err)=>{console.log("[ERROR]--路线规划WALKING请求出错",err)})
    }

    if(this.data.currentBtn_SELECT == 2){//请求公交车规划的数据，但是这个数据真的超级麻烦。
      /**
       * 这个数据分为多段，steps中有几种不同的类型的步骤，靠mode分辨，好像有WALKING,TRANSIT两种
       * mode:WALKING，这个数据和驾车步行的数据一致
       * mode:TRANSIT，这个数据有两种，一种是bus，一种是subway，一种是railway。都有polyline和经过站点之类的，绘制起来估计很麻烦
       * bus和subway的数据结构感觉一样，railway的有点不一样
       */
      let request = tool.getRoutePlan_BUSLINE(from,to);
      request.then((res)=>{
        console.log("[REQUEST] -- 处理后的公交信息：",res);
        
        //保存路线信息
        this.setData({
          routes: res.data.result.routes
        });

        //调用初始路线规划功能，默认绘制第一条路线
        this.drawThreeRoute_ForBUS(0);

      },(err)=>{
        console.log("[REQUEST][ERROR] -- 公交线路请求出错",err);
        wx.showToast({
          title: '距离过近公交无效',
        });
      });

    }

    
  },

  /**
   * 生命周期函数--监听页面加载
   */
  onLoad: function (options) {
    //界面上有的组件是使用了百分比单位，所以在这里查询获取一下，方便制作动画
    let query = this.createSelectorQuery().in(this);
    query.select('.selectItem').boundingClientRect(
      (res)=>{
        this.setData({
          item_width:res.width
        });
      }
    ).exec();
  },

  /**
   * 生命周期函数--监听页面初次渲染完成
   */
  onReady: function () {

  },

  /**
   * 生命周期函数--监听页面显示
   */
  onShow: function () {
    //单纯设置一下地图初试的中心位置
    let that = this;
    wx.getLocation({
      success:function(res){
        console.log("当前用户所在位置："+res.longitude+", "+res.latitude)
        that.setData({
          latitude:res.latitude,
          longitude:res.longitude
        })
      }
    });
  },

  /**
   * 生命周期函数--监听页面隐藏
   */
  onHide: function () {

  },

  /**
   * 生命周期函数--监听页面卸载
   */
  onUnload: function () {

  },

  /**
   * 页面相关事件处理函数--监听用户下拉动作
   */
  onPullDownRefresh: function () {

  },

  /**
   * 页面上拉触底事件的处理函数
   */
  onReachBottom: function () {

  },

  /**
   * 用户点击右上角分享
   */
  onShareAppMessage: function () {

  },


/**
 * 一个带有防抖的函数，用来发送请求，获取地址建议
 * @param {context} 把this传递过去就行了，直接全局获取参数
 */
  Suggestion_Debounce: utils.debounce((context)=>{
    //请求腾讯位置服务的关键词提示服务
    
    context.setData({//设置正在加载中
      isLoading_START:true
    });

    wx.request({
      url: 'https://apis.map.qq.com/ws/place/v1/suggestion',
      method: 'GET',
      data:{
        key: '64CBZ-OA5K4-KH3UV-DMCQX-2P4MJ-VJFQD',
        keyword: context.data.keyword,
        region: '广州',
        page_index: context.data.page_index,
        page_size: context.data.page_size
      },
      success:function(res){
        console.log(res);
        if(res.data.status == 0){
          context.setData({//加载完成之后关闭加载项
            isLoading_START:false
          });

          if(res.data.count == 0){//关键词搜索不出来的情况下
            console.log("关键词错误")
            context.setData({
              locationList:[]
            });
            context.LocationListDisplay();//刷新一下动画
          }else{
            console.log("[INFO] -- 提示词请求成功")
            //将返回的数据插入到locationList中
            let originArray = context.data.locationList;
            let finalArray = originArray.concat(res.data.data);
            context.setData({
              locationList: finalArray,
              count: res.data.count,
            });
            context.LocationListDisplay();//刷新一下动画
          }
        }else{
          console.log("[ERROR] -- 错误代码:",res.data.status);
        }
      }
    })

  },500,false),


  //终点位置的建议请求，写成两个是为了不污染数据
  Suggestion_Debounce_END: utils.debounce((context)=>{
    //请求腾讯位置服务的关键词提示服务
    context.setData({//设置正在加载中
      isLoading_END:true
    })
    wx.request({
      url: 'https://apis.map.qq.com/ws/place/v1/suggestion',
      method: 'GET',
      data:{
        key: '64CBZ-OA5K4-KH3UV-DMCQX-2P4MJ-VJFQD',
        keyword: context.data.keyword_END,
        region: '广州',
        page_index: context.data.page_index_END,
        page_size: context.data.page_size_END
      },
      success:function(res){
        console.log(res);
        if(res.data.status == 0){
          //设置加载完成
          context.setData({
            isLoading_END:false
          });


          if(res.data.count == 0){//关键词搜索不出来的情况下
            console.log("关键词错误")
            context.setData({
              locationList_END:[]
            });
            context.LocationListDisplay_END();//刷新一下动画
          }else{
            console.log("提示词请求成功")
            //将返回的数据插入到locationList中
            let originArray = context.data.locationList_END;
            let finalArray = originArray.concat(res.data.data);
            context.setData({
              locationList_END: finalArray,
              count_END: res.data.count,
            });
            context.LocationListDisplay_END();//刷新一下动画
          }
        }else{
          console.log("错误代码:",res.data.status);
        }
      }
    })

  },500,false),
  
//逆地址解析，是地图右下角定位使用的，将经纬度信息逆地址转化为 TAG DEBOUNCE
Geocoder:utils.debounce((context)=>{
  context.setData({
    isLoading_POSITION: true, //设置正在加载中，界面可能要用到
    center_location:'',
  });

  //向腾讯位置服务发送逆地址解析服务
  wx.request({
    url: 'https://apis.map.qq.com/ws/geocoder/v1/',
    method: 'GET',
    data: {
        key: '64CBZ-OA5K4-KH3UV-DMCQX-2P4MJ-VJFQD',
        location: context.data.center_latitude + ',' + context.data.center_longitude
    },
    success:function(res){
      console.log("[REQUEST][geoCode] -- 逆地址解析",res)
      if(res.data.status == 0){//请求地址成功之后，需要做的事情有两件，一是将地址数据保存到地址栏中去，二是构造一个point对象，提供给路线规划使用
        let address = typeof(res.data.result.formatted_addresses.recommend) == undefined? '该地点无法解析' : res.data.result.formatted_addresses.recommend;
        //构造出来的假点，数据不完整，但也够用了
        let temple_point = {
          title: address,
          location: {
            lat: res.data.result.location.lat,
            lng: res.data.result.location.lng
          }
        }
        
        context.setData({
          center_location: address, //地址，界面显示用
          center_point: temple_point,
          isLoading_POSITION:false
        })

      }
    },
    fail:function(res){
      console.log("[REQUEST][geocode]",res)
      wx.showToast({
        title: '地址解析失败',
      })
    }
  });



},500,false)



})